﻿using CastingWellEquipmentGUI.Dao;
using CastingWellEquipmentGUI.Model;
using CastingWellEquipmentGUI.ViewModel.Common.LogTool;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Net.NetworkInformation;
using System.Security.Cryptography;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace CastingWellEquipmentGUI.Utils
{
    /// <summary>
    /// 徐一贺自定义工具类
    /// </summary>
    public static class XyhUtils
    {

        private static List<string> excludeControlNames = new List<string>() {
            "Button_EndAirbagPressure_Small_Right",
            "Button_EndAirbagPressure_Big_Left",
            "Button_EndAirbagPressure_Small_Left",
            "Button_RollingSurfaceAirBagPressure_Big_Upper",
            "Button_RollingSurfaceAirBagPressure_Small_Upper",
            "Button_RollingSurfaceAirBagPressure_Big_Lower",
            "Button_RollingSurfaceAirBagPressure_Small_Lower",
            "Button_EndAirbagPressure_Big_Right",
            "Button_EndAirbagPressure_Small_Right"
        };

        public static ObservableCollection<Model.Control> PermissionControl(FrameworkElement frameworkElement, string frameworkElementName)
        {
            ObservableCollection<Model.Control> controls = new ObservableCollection<Model.Control>();
            ObservableCollection<Role> roles = LogTool.CurrentUser.Roles;
            for (int i = 0; i < roles.Count; i++)
            {
                ObservableCollection<Permissions> permissions = roles[i].Permissions;
                for (int j = 0; j < permissions.Count; j++)
                {

                    if (permissions[j].PForm != null && permissions[j].PForm.FormName == frameworkElementName)
                    {
                        if (excludeControlNames.Contains(permissions[j].PControl.ControlName))
                        {
                            continue;
                        }
                        System.Windows.Controls.Control control = frameworkElement.FindName(permissions[j].PControl.ControlName) as System.Windows.Controls.Control;
                        if (control != null)
                        {
                            controls.Add(permissions[j].PControl);
                            control.IsEnabled = permissions[j].IsEnable;
                            if (permissions[j].IsShow)
                            {
                                control.Visibility = Visibility.Visible;
                            }
                            else
                            {
                                control.Visibility = Visibility.Hidden;
                            }
                        }
                    }
                }
            }
            return controls;

        }
        /// <summary>
        /// 获取当前控件的子集控件
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="root">当前父级控件的Name</param>
        /// <returns></returns>
        private static List<T> FindChildOfType<T>(DependencyObject root) where T : class
        {
            var queue = new Queue<DependencyObject>();
            List<T> resultList = new List<T>();
            queue.Enqueue(root);
            while (queue.Count > 0)
            {
                DependencyObject current = queue.Dequeue();
                for (int i = VisualTreeHelper.GetChildrenCount(current) - 1; 0 <= i; i--)
                {
                    var child = VisualTreeHelper.GetChild(current, i);
                    var typedChild = child as T;
                    if (typedChild != null)
                    {
                        resultList.Add(typedChild);
                    }
                    queue.Enqueue(child);
                }
            }
            return resultList;
        }


        /// <summary>
        /// 获取本电脑的GUID
        /// </summary>
        /// <returns></returns>
        public static string GetGuid()
        {
            #region 获取本地电脑的GUID
            try
            {
                string x64Result = string.Empty;
                string x86Result = string.Empty;
                //此处如果需要可以判断一下系统是什么位数的,比如32或者64,用以取分读取哪个视图,因为视图不同,获得的数据也不同
                RegistryKey keyBaseX64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
                RegistryKey keyBaseX86 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
                RegistryKey keyX64 = keyBaseX64.OpenSubKey(@"SOFTWARE\Microsoft\Cryptography", RegistryKeyPermissionCheck.ReadSubTree);
                RegistryKey keyX86 = keyBaseX86.OpenSubKey(@"SOFTWARE\Microsoft\Cryptography", RegistryKeyPermissionCheck.ReadSubTree);
                object resultObjX64 = keyX64.GetValue("MachineGuid", (object)"default");
                object resultObjX86 = keyX86.GetValue("MachineGuid", (object)"default");
                keyX64.Close();
                keyX86.Close();
                keyBaseX64.Close();
                keyBaseX86.Close();
                keyX64.Dispose();
                keyX86.Dispose();
                keyBaseX64.Dispose();
                keyBaseX86.Dispose();
                keyX64 = null;
                keyX86 = null;
                keyBaseX64 = null;
                keyBaseX86 = null;
                if (resultObjX64 != null && resultObjX64.ToString() != "default")
                {
                    return resultObjX64.ToString();
                }
                if (resultObjX86 != null && resultObjX86.ToString() != "default")
                {
                    return resultObjX86.ToString();
                }
            }
            catch (Exception)
            {

            }
            return "无法识别！";
            #endregion
        }



        /// <summary>
        /// GetParentObject方法，获取父控件方法。该方法将根据当前控件，遍历查找其父控件是否存在。使用VisualTreeHelper.GetParent方法获取当前父控件。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">参数1是表示当前子控件名</param>
        /// <param name="name">参数2是要查询父控件名</param>
        /// <returns></returns>
        public static T GetParentObject<T>(DependencyObject obj, string name) where T : FrameworkElement
        {
            DependencyObject parent = VisualTreeHelper.GetParent(obj);

            while (parent != null)
            {
                if (parent is T && (((T)parent).Name == name | string.IsNullOrEmpty(name)))
                {
                    return (T)parent;
                }
                parent = VisualTreeHelper.GetParent(parent);
            }
            return null;
        }
        /// <summary>
        /// GetChildObject,获取子控件方法。该方法将根据当前控件，遍历查找其子控件是否存在。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">参数1是表示当前父控件名</param>
        /// <param name="name">参数2是要查询子控件名</param>
        /// <returns></returns>
        public static T GetChildObject<T>(DependencyObject obj, string name) where T : FrameworkElement
        {
            DependencyObject child = null;
            T grandChild = null;

            for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
            {
                child = VisualTreeHelper.GetChild(obj, i);

                if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name)))
                {
                    return (T)child;
                }
                else
                {
                    grandChild = GetChildObject<T>(child, name);
                    if (grandChild != null)
                        return grandChild;
                }
            }
            return null;
        }
        /// <summary>
        /// GetChildObjects方法，该方法将把所有子控件作为List集合返回到客户端。如果需要遍历全部子控件，第二个参数留空即可。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">第一个参数是父控件参数</param>
        /// <param name="name">第二个参数是特定子控件名称</param>
        /// <returns></returns>
        public static List<T> GetChildObjects<T>(DependencyObject obj, string name) where T : FrameworkElement
        {
            DependencyObject child = null;
            List<T> childList = new List<T>();

            for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
            {
                child = VisualTreeHelper.GetChild(obj, i);

                if (child is T && (((T)child).Name == name || string.IsNullOrEmpty(name)))
                {
                    childList.Add((T)child);
                }
                childList.AddRange(GetChildObjects<T>(child, ""));
            }
            return childList;
        }

        /// <summary>
        /// 字符串过滤，防止sql注入。
        /// </summary>
        /// <param name="str">被检测的SQL字符串</param>
        /// <returns></returns>
        public static bool IsHasSQLInject(string str)
        {
            bool isHasSQLInject = false;

            //字符串中的关键字更具需要添加
            string inj_str = "'|and|exec|union|create|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|xp_|or|--|+";
            str = str.ToLower().Trim();
            string[] inj_str_array = inj_str.Split('|');
            foreach (string sql in inj_str_array)
            {
                if (str.IndexOf(sql) > -1)
                {
                    isHasSQLInject = true;
                    break;
                }
            }
            return isHasSQLInject;
        }


        /// <summary> 
        /// Find Child with Visual Tree 
        /// </summary> 
        /// <typeparam name="T">specail type</typeparam> 
        /// <param name="root">the element starts</param> 
        /// <returns></returns> 
        public static T FindChild<T>(DependencyObject root) where T : DependencyObject
        {
            if (root == null)
                return null;

            T founded = null;

            for (int j = 0; j < VisualTreeHelper.GetChildrenCount(root); j++)
            {
                DependencyObject d = VisualTreeHelper.GetChild(root, j);
                T childType = d as T;
                if (childType == null)
                {
                    founded = FindChild<T>(d);
                    if (founded != null)
                        break;
                }
                else
                {
                    founded = childType;
                    break;
                }
            }

            return founded;
        }



        /// <summary>
        /// 默认密钥-密钥的长度必须是32
        /// </summary>
        private const string PublicKey = "567890abcdefghijklmnopqrstuvwxyh";

        /// <summary>
        /// 默认向量
        /// </summary>
        private const string Iv = "abcdefghijklmnop";
        /// <summary>  
        /// AES加密  
        /// </summary>  
        /// <param name="str">需要加密字符串</param>  
        /// <returns>加密后字符串</returns>  
        public static String Encrypt(string str)
        {
            return AesEncrypt(str, PublicKey);
        }

        /// <summary>  
        /// AES解密  
        /// </summary>  
        /// <param name="str">需要解密字符串</param>  
        /// <returns>解密后字符串</returns>  
        public static String Decrypt(string str)
        {
            return AesDecrypt(str, PublicKey);
        }
        /// <summary>
        ///  AES 加密
        /// </summary>
        /// <param name="str">明文（待加密）</param>
        /// <param name="key">密文</param>
        /// <returns></returns>
        public static string AesEncrypt(string str, string key)
        {
            if (string.IsNullOrEmpty(str)) return null;
            Byte[] toEncryptArray = Encoding.UTF8.GetBytes(str);

            RijndaelManaged rm = new RijndaelManaged
            {
                Key = Encoding.UTF8.GetBytes(key),
                Mode = CipherMode.ECB,
                Padding = PaddingMode.PKCS7
            };

            ICryptoTransform cTransform = rm.CreateEncryptor();
            Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }
        /// <summary>
        ///  AES 解密
        /// </summary>
        /// <param name="str">明文（待解密）</param>
        /// <param name="key">密文</param>
        /// <returns></returns>
        public static string AesDecrypt(string str, string key)
        {
            if (string.IsNullOrEmpty(str)) return null;
            Byte[] toEncryptArray = Convert.FromBase64String(str);

            RijndaelManaged rm = new RijndaelManaged
            {
                Key = Encoding.UTF8.GetBytes(key),
                Mode = CipherMode.ECB,
                Padding = PaddingMode.PKCS7
            };

            ICryptoTransform cTransform = rm.CreateDecryptor();
            Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            return Encoding.UTF8.GetString(resultArray);
        }

        /// <summary>
        /// ping ip,测试能否ping通
        /// </summary>
        /// <param name="strIP">IP地址</param>
        /// <returns></returns>
        public static bool PingIp(string IPAddress)
        {
            bool PingResult = false;
            try
            {
                Ping pingSend = new Ping();
                PingReply reply = pingSend.Send(IPAddress, 1000);
                if (reply.Status == IPStatus.Success)
                {
                    PingResult = true;
                }
            }
            catch (Exception e)
            {
                LogTool.SaveLog("pingPLC地址异常", e.Message);
                PingResult = false;
            }
            return PingResult;
        }
    }
}
